package modes

import (
	"fmt"
	"time"
)

/*题库收藏记录*/
type TopicErr struct {
	Id     int64 `json:"id" xorm:"id"`           //错题id
	PId    int64 `json:"pid" xorm:"pid"`         //项目id
	SId    int64 `json:"sid" xorm:"sid"`         //科目id
	SQId   int64 `json:"sqid" xorm:"sqid"`       //章节id
	NId    int64 `json:"nid" xorm:"nid"`         //套题id
	TId    int64 `json:"tid" xorm:"tid"`         //题id
	UId    int64 `json:"uid" xorm:"uid"`         //学员id
	TypeId int   `json:"type_id" xorm:"type_id"` //题型类型： 1:历年真题;2:章节练习题;3:模拟题
	At     int64 `json:"at" xorm:"at"`           //添加时间
}

func (this *TopicErr) TableName() string {
	return "topic_err"
}
func (this *TopicErr) Save() (int64, error) {
	this.At = time.Now().Unix()
	return Db(1).Insert(this)
}

func (this *TopicErr) Get() (bool, error) {
	return Db(1).Get(this)
}
func (this *TopicErr) delete(where string) (int64, error) {
	return Db(1).Where(where).Delete(this)
}
func (this *TopicErr) Del() (int64, error) {
	where := fmt.Sprintf("id =%d", this.Id)
	return this.delete(where)
}
func (this *TopicErr) Count(where string) (int64, error) {
	var val TopicErr
	return Db(1).Where(where).Count(&val)
}
func (this *TopicErr) update(where string, field string) (int64, error) {
	return Db(1).Where(where).Cols(field).Update(this)
}

func (this *TopicErr) IdSet(field string) (int64, error) {
	where := fmt.Sprintf("id = %d", this.Id)
	return this.update(where, field)
}

func (this *TopicErr) where(fage, count, page int, where, field string) ([]TopicErr, error) {
	list := make([]TopicErr, 0)
	var err error
	if field == "" {
		field = "id"
	}
	if 0 == fage { // 从小到大排序
		err = Db(1).Where(where).
			Asc(field).
			Limit(count, page*count).
			Find(&list)
	} else { // 从大到小排序
		err = Db(1).Where(where).
			Desc(field).
			Limit(count, page*count).
			Find(&list)
	}
	return list, err
}

func (this *TopicErr) GetList() ([]int64, error) {
	tidList := make([]int64, 0)
	err := Db(1).Table(this.TableName()).Cols("tid").Distinct("tid").Where("uid=? and  type_id=? and sid=?", this.UId, this.TypeId, this.SId).Find(&tidList)
	return tidList, err
}
func (this *TopicErr) TCount() (int64, error) {
	list := make([]int64, 0)
	err := Db(1).SQL(fmt.Sprintf("SELECT  count(distinct tid) FROM `topic_err` WHERE (topic_err.uid=%d and topic_err.type_id=%d and topic_err.sid=%d)", this.UId, this.TypeId, this.SId)).
		Find(&list)
	if list != nil && len(list) > 0 {
		return list[0], nil
	}
	return 0, err
}

func (this *TopicErr) SqInfo() ([]SqInfo, error) {
	sqInfoList := make([]SqInfo, 0)
	err := Db(1).Table(this.TableName()).Select(" COUNT(DISTINCT tid) total,sqid id ").GroupBy("sqid").Where("uid=? and  sid=? and  type_id=?", this.UId, this.SId, this.TypeId).Find(&sqInfoList)
	if err != nil || sqInfoList == nil || len(sqInfoList) <= 0 {
		return make([]SqInfo, 0), err
	}
	subjectQues := SubjectQues{}
	quesList, err := subjectQues.GetListBySId()

	for i, sqInfo := range sqInfoList {
		for _, ques := range quesList {
			if ques.Id == sqInfo.Id {
				sqInfoList[i].Name = ques.Name
				break
			}
		}

	}
	return sqInfoList, nil

}

func (this *TopicErr) DelTidUid() (int64, error) {
	where := fmt.Sprintf("tid =%d and uid=%d ", this.TId, this.UId)
	return this.delete(where)
}

func (this *TopicErr) SaveList(list []TopicErr) error {
	const BatchSize = 100

	items := []TopicErr{}
	for _, rId := range list {
		items = append(items, rId)
	}
	for n := 0; ; n++ {
		end := (n + 1) * BatchSize
		if end >= len(items) {
			end -= (end - len(items))
		}

		_, err := Db(1).Table(this).Insert(items[n*BatchSize : end])
		if err != nil {
			return err
		}

		if end >= len(items) {
			break
		}
	}
	return nil

}

func (this *TopicErr) GetListBySUT() ([]int64, error) {
	tidList := make([]int64, 0)
	err := Db(1).Table(this.TableName()).Cols("tid").Distinct("tid").
		Where("uid=? and type_id=? and sqid=?", this.UId, this.TypeId, this.SQId).
		Find(&tidList)
	return tidList, err
}

func (this *TopicErr) GetListByUid() ([]int64, error) {
	list := make([]int64, 0)
	err := Db(1).Table(this.TableName()).Select("tid").Distinct("tid").Asc("tid").Where(fmt.Sprintf(" uid=%d ", this.UId)).Find(&list)
	return list, err
}

func (this *TopicErr) UpdateAt(tidList []int64) (bool, error) {
	this.At = time.Now().Unix()
	_, err := Db(1).In("tid", tidList).Where("uid=?", this.UId).Cols("at").Update(this)
	if err != nil {
		return false, err
	}
	return true, err
}
